<?php

namespace App\Model;

use App\Services\AliPayService;
use App\Services\WechatService;
use Carbon\Carbon;
use Hyperf\Database\Model\Relations\BelongsTo;
use Hyperf\Utils\Arr;

/**
 * App\PaymentOrder
 *
 * @property int $id
 * @property int $user_id 用户
 * @property int $device_id 用户
 * @property int $fee 金额
 * @property \App\Model\User $user 用户模型
 * @property int $give_fee 退款金额
 * @property string $number 订单号
 * @property string $type 类型
 * @property \Carbon\Carbon|null $paid_at 支付时间
 * @property string $payment_type 支付方式
 * @property array|null $extra 其他信息
 */
class BalanceOrder extends Model
{
    public bool $timestamps = true;
    protected ?string $table = 'balance_orders';


    const STATUS_UNPAID = 'unpaid';
    const STATUS_PAID = 'paid';
    const STATUS_FAILED = 'failed';
    const STATUS_REFUNDED = 'refunded';

    const USER_SOURCE_TO_PAYMENT_TYPE = [
        User::SOURCE_ALI_PAY => Bill::PAYMENT_TYPE_ALI_PAY,
        User::SOURCE_WE_CHAT => Bill::PAYMENT_TYPE_WE_CHAT_PAY,
    ];


    protected array $fillable = [
        'type', 'number', 'payment_type',
        'extra' ,'status','out_ord_id','user_id',
        'fee','paid_at','give_fee','payment_id','device_id','return_fee'
    ];

    protected array $casts = [

    ];

    public function user():BelongsTo
    {
        return $this->belongsTo(User::class,'user_id','id');
    }

    /**充值余额支付后逻辑
     * @param array $params
     * @return void
     */
    public function balanceNotify(){
            $this->status = self::STATUS_PAID;
            $this->paid_at = date('Y-m-d H:i:s');
            $this->save();
            $this->user->balance+=$this->fee;
            $this->user->save();
            $couponCache = "coupon_cache_key".$this->id;
            if($this->device_id){
                if(redis()->exists($couponCache)){
                    return 'succeeded';
                }
                $device = Device::where('id',$this->device_id)->first();
                if($device->child_distributor_id > 0){
                    $distributorId = $device->child_distributor_id;
                }else{
                    $distributorId = $device->distributor_id;
                }
                $today = date('Y-m-d',time());
                $coupon = Coupon::where('distributor_id',$distributorId)
                    ->where('type',Coupon::TYPE_MAP[Coupon::TYPE_RECHARGE_RECEIVE])
                    ->where('start_date','<=', $today)
                    ->where('end_date','>=',$today)
                    ->where('is_active',1)
                    ->orderBy('id','desc')
                    ->first();
                $number = 0;
                if($coupon){
                    $cacheKey = Coupon::COUPON_MONEY_CACHE . $coupon->id;
                    $receiveData = redis()->hGetAll($cacheKey);
                    $cacheDevice = Coupon::COUPON_DEVICE_CACHE . $coupon->id;
                    $devices = redis()->sMembers($cacheDevice);
                    if(!in_array($this->device_id,$devices)){
                        redis()->setex($couponCache,60*10,1);
                        return '';
                    }
                    if($receiveData){
                        krsort($receiveData);
                        foreach($receiveData as $k => $v){
                            if($this->fee >= $k){
                                $number = (int)$v;
                                break;
                            }
                        }
                    }
                    $insertRecord =[];
                    try{
                        for($i=0; $i<$number; $i++){
                            $insertRecord[] = [
                                'coupon_id'=> $coupon->id,
                                'user_id'=>$this->user_id,
                                'expires_at'=>date('Y-m-d H:i:s',time()+(60*60*24*$coupon->days)),
                                'device_id' =>$device->id,
                                'station_id'=>$device->station_id,
                                'created_at'=>date('Y-m-d H:i:s',time())
                            ];
                        }
                         CouponRecord::insert($insertRecord);
                         redis()->setex($couponCache,60*10,1);
                    }catch (\Exception $e){
                        echo $e->getMessage();
                    }

                }
            }
    }

    public function distributorSettle(){
        if($this->device_id){
            $deviceModel = Device::where('id',$this->device_id)->first();
            $firstDis = Distributors::where('id',$deviceModel->distributor_id)
                ->first();
            if($deviceModel->child_distributor_id){
                $childDis = Distributors::where('id',$deviceModel->child_distributor_id)
                    ->first();
                $disMoney = number_format($this->fee*$childDis->rate/100,2);
                $childDis->balance+=$disMoney;
                $childDis->save();
                $profit['profit'] = $disMoney;
                $profit['distributor_id'] = $childDis->id;
                $profit['device_id'] = $this->device_id;
                DistributorDevice::create($profit);
                Bill::record(
                    $childDis,
                    $disMoney,
                    Bill::TYPE_ORDER_PAY,
                    $this->payment_type,
                    $this->id
                );
                if($firstDis->rate > $childDis->rate){
                    $firstRate = $firstDis->rate-$childDis->rate;
                    if($firstRate > 0){
                        $firstMoney = number_format($this->fee*$firstRate /100,2);
                        $firstDis->balance+=$firstMoney;
                        $firstDis->save();
                        $profit['profit'] = $firstMoney;
                        $profit['distributor_id'] = $firstDis->id;
                        $profit['device_id'] = $this->device_id;
                        DistributorDevice::create($profit);
                        Bill::record(
                            $firstDis,
                            $firstMoney,
                            Bill::TYPE_ORDER_PAY,
                            $this->payment_type,
                            $this->id
                        );
                    }
                }
            }else{
                $firstMoney = number_format($this->fee*$firstDis->rate/100,2);
                $firstDis->balance +=$firstMoney;
                $firstDis->save();
                $profit['profit'] = $firstMoney;
                $profit['distributor_id'] = $firstDis->id;
                $profit['device_id'] = $this->device_id;
                DistributorDevice::create($profit);
                Bill::record(
                    $firstDis,
                    $firstMoney ,
                    Bill::TYPE_ORDER_PAY,
                    $this->payment_type,
                    $this->id
                );
            }
        }
    }

}
